#include "gamelua.h"
#include "gamecore.h"
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}

static bool _initialized = false;
static lua_State *_L = NULL;
static GameCore *_core = NULL;

/* arg1:player arg2:value*/
static int change_hitpoint(lua_State *L)
{
    int n = 0;
    int action_player = 0;
    int c_hp = 0;
    Player *player_me = NULL;
    Player *player_enemy = NULL;

    if (_core->cur_playerID == GameCore::PLAYER_1) {
        player_me = _core->player1;
        player_enemy = _core->player2;
    } else if (_core->cur_playerID == GameCore::PLAYER_2) {
        player_me = _core->player2;
        player_enemy = _core->player1;
    }
    /* two arguments*/
    n = lua_gettop(L);
    if (n < 2) {
        lua_pushstring(L, "too few argument to 'change_hitpoint'");
        return lua_error(L);
    }

    if (!lua_isnumber(L, 1)) {
        lua_pushstring(L, "Incorrect argument 1 to 'change_hitpoint'");
        return lua_error(L);
    }
    action_player = (int)lua_tonumber(L, 1);

    if (!lua_isnumber(L, 2)) {
        lua_pushstring(L, "Incorrect argument 2 to 'change_hitpoint'");
        return lua_error(L);
    }
    c_hp = (int)lua_tonumber(L, 2);

    if (action_player == 1) {
        player_me->change_hitpoint(c_hp);
    } else if (action_player == 2) {
        player_enemy->change_hitpoint(c_hp);
    } else {
        lua_pushstring(L, "Incorrect argument 1 to 'change_hitpoint'");
        return lua_error(L);
    }

    return 0;
}

/* arg1:player
 * arg2:mana type
 * arg3:value
 */
static int change_manapoint(lua_State *L)
{
    int n = 0;
    int action_player = 0;
    enum MagicColor mana_type;
    int value = 0;
    Player *player_me = NULL;
    Player *player_enemy = NULL;

    if (_core->cur_playerID == GameCore::PLAYER_1) {
        player_me = _core->player1;
        player_enemy = _core->player2;
    } else if (_core->cur_playerID == GameCore::PLAYER_2) {
        player_me = _core->player2;
        player_enemy = _core->player1;
    }
    /* three arguments*/
    n = lua_gettop(L);
    if (n < 3) {
        lua_pushstring(L, "too few argument to 'change_manapoint'");
        return lua_error(L);
    }

    if (!lua_isnumber(L, 1)) {
        lua_pushstring(L, "Incorrect argument 1 to 'change_manapoint'");
        return lua_error(L);
    }
    action_player = (int)lua_tonumber(L, 1);

    if (!lua_isnumber(L, 2)) {
        lua_pushstring(L, "Incorrect argument 2 to 'change_manapoint'");
        return lua_error(L);
    }
    switch ((int)lua_tonumber(L, 2)) {
    case 0:
        mana_type = MAGIC_GREEN;
        break;
    case 1:
        mana_type = MAGIC_BLUE;
        break;
    case 2:
        mana_type = MAGIC_RED;
        break;
    default:
        lua_pushstring(L, "Incorrect argument 2 to 'change_manapoint'");
        return lua_error(L);
    }

    if (!lua_isnumber(L, 3)) {
        lua_pushstring(L, "Incorrect argument 3 to 'change_manapoint'");
        return lua_error(L);
    }
    value = (int)lua_tonumber(L, 3);

    if (action_player == 1) {
        player_me->change_manapoint(mana_type, value);
    } else if (action_player == 2) {
        player_enemy->change_manapoint(mana_type, value);
    } else {
        lua_pushstring(L, "Incorrect argument 1 to 'change_manapoint'");
        return lua_error(L);
    }

    return 0;
}

int gamelua_init(GameCore *gcore)
{
    if (_initialized) {
        return 0;
    }
    if (gcore == NULL) {
        return -1;
    }
    _core = gcore;

    _L = luaL_newstate();
    if (_L == NULL) {
        return -1;
    }
    /* Opens all standard Lua libraries */
    luaL_openlibs(_L);
    /* register our functions */
    lua_register(_L, "change_hitpoint", change_hitpoint);
    lua_register(_L, "change_manapoint", change_manapoint);
    _initialized = true;
    return 0;
}

int gamelua_close()
{
    if (!_initialized) {
        return 0;
    }
    lua_close(_L);
    _core = NULL;
    _initialized = false;
    return 0;
}

int gamelua_do(const char *str)
{
    int ret = 0;
    if (str == NULL) {
        return -1;
    }
    ret = luaL_dostring(_L, str);
    if (ret != 0) {
        return -1;
    }
    return 0;
}
